import React, { useState, useEffect, useMemo, useImperativeHandle, useCallback } from 'react';
import PropTypes from 'prop-types';
import { Popover, Icon as AntIcon, Button } from 'antd';
import classNames from 'classnames';
import Icon from './Icon';
import { combineIconValue, parseIconValue } from './utils';
import styles from './index.module.less';

/**
 * 图标选择器
 * @param props
 * @returns {JSX.Element}
 * @constructor
 */
const IconSelector = React.forwardRef((props, ref) => {
    const {
        value,
        onChange,
        iconfontClassName,
        colorList,
        iconList,
        defaultSelectFirstOption,
        disabled,
        disabledOptions
    } = props;
    const [selectedColor, setSelectedColor] = useState('');
    const [selectedIcon, setSelectedIcon] = useState(null);

    // 禁用的颜色列表
    const disabledColorList = useMemo(() => {
        if (selectedIcon && disabledOptions) {
            return disabledOptions.filter(option => option.includes(selectedIcon));
        }
        return [];
    }, [disabledOptions, selectedIcon]);
    // 禁用的图标列表
    const disabledIconList = useMemo(() => {
        if (selectedColor && disabledOptions) {
            return disabledOptions.filter(option => option.includes(selectedColor));
        }
        return [];
    }, [disabledOptions, selectedColor]);

    const setDefaultValue = useCallback(
        (_value, _onChange) => {
            if (defaultSelectFirstOption && !_value) {
                let isEnd = false;
                for (let i = 0; i < colorList.length; i += 1) {
                    for (let j = 0; j < iconList.length; j += 1) {
                        const currentValue = combineIconValue(iconList[j], colorList[i]);
                        if (!disabledOptions || !disabledOptions.some(item => item === currentValue)) {
                            _onChange(currentValue);
                            isEnd = true;
                            break;
                        }
                    }
                    if (isEnd) {
                        break;
                    }
                }
            }
        },
        [colorList, defaultSelectFirstOption, disabledOptions, iconList]
    );

    // 设置默认值
    useEffect(
        () => {
            setDefaultValue(value, onChange);
        },
        // eslint-disable-next-line react-hooks/exhaustive-deps
        [setDefaultValue]
    );

    // value变化, 解析value, 设置图标和颜色
    useEffect(
        () => {
            const parsedValue = parseIconValue(value);
            if (parsedValue && parsedValue.iconName) {
                setSelectedIcon(parsedValue.iconName);
                setSelectedColor(parsedValue.color || '#999');
            } else {
                setDefaultValue(value, onChange);
            }
        },
        // eslint-disable-next-line react-hooks/exhaustive-deps
        [value]
    );

    // 颜色渲染
    const handleColorClick = (color, isDisabled) => {
        if (isDisabled) {
            setSelectedIcon(null);
            setSelectedColor(color);
        } else if (selectedIcon) {
            onChange(combineIconValue(selectedIcon, color));
            if (color === parseIconValue(value)?.color) {
                setSelectedColor(color);
            }
        } else {
            setSelectedColor(color);
        }
    };
    const renderColor = (color, isSelected) => {
        const iconColor = color?.split('|')[0];
        const isDisabled = disabledColorList.some(item => item.includes(color));
        return (
            <div
                key={color}
                className={classNames(styles.colorOption, [
                    isSelected && styles.colorOptionSelected,
                    isDisabled && styles.colorOptionDisabled
                ])}
                style={{ borderColor: isSelected ? iconColor : null }}
                onClick={() => handleColorClick(color, isDisabled)}
            >
                <div className={styles.colorOptionInner} style={{ backgroundColor: iconColor }}>
                    {isSelected && <AntIcon type="check" />}
                </div>
            </div>
        );
    };

    // 图标选项;
    const handleIconClick = (iconName, isDisabled) => {
        if (isDisabled) {
            setSelectedIcon(iconName);
            setSelectedColor(null);
        } else if (selectedColor) {
            onChange(combineIconValue(iconName, selectedColor));
            if (iconName === parseIconValue(value)?.iconName) {
                setSelectedIcon(iconName);
            }
        } else {
            setSelectedIcon(iconName);
        }
        // onChange(combineIconValue(iconName, isDisabled ? null : selectedColor));
    };

    const handleVisibleChange = visible => {
        if (!visible) {
            const parsedValue = parseIconValue(value);
            if (parsedValue && parsedValue.iconName) {
                setSelectedIcon(parsedValue.iconName);
                setSelectedColor(parsedValue.color || '#999');
            }
        }
    };

    // 解析图标源配置
    const renderIcon = (iconName, isSelected) => {
        const iconColor = selectedColor?.split('|')[0];
        const isDisabled = disabledIconList.some(item => item.includes(iconName));
        return (
            <div
                key={iconName}
                className={classNames(styles.iconOptionWrap, [isDisabled && styles.iconOptionDisabled])}
                style={{ borderColor: iconName === selectedIcon ? iconColor || '#eee' : null }}
            >
                <Icon
                    iconfontClassName={iconfontClassName}
                    icon={{ iconName, color: isSelected ? selectedColor : '#999' }}
                    className={classNames(styles.iconOption)}
                    onClick={() => handleIconClick(iconName, isDisabled)}
                />
            </div>
        );
    };

    useImperativeHandle(ref, () => ({}));

    return (
        <div className={styles.iconSelectorInputWrap}>
            <div className={styles.iconSelectorInput}>
                {selectedIcon && selectedColor && (
                    <Icon
                        iconfontClassName={iconfontClassName}
                        icon={{ iconName: selectedIcon, color: selectedColor }}
                    />
                )}
            </div>
            {!disabled && (
                <Popover
                    placement="rightTop"
                    getPopupContainer={trigger => trigger.parentNode}
                    trigger="click"
                    onVisibleChange={handleVisibleChange}
                    content={
                        <div className={styles.iconSelectorPopup}>
                            <div className={styles.colorList}>
                                {colorList.map(color => renderColor(color, color === selectedColor))}
                            </div>
                            <div className={styles.line} />
                            <div className={styles.iconList}>
                                {iconList.map(iconName => renderIcon(iconName, iconName === selectedIcon))}
                            </div>
                        </div>
                    }
                >
                    <Button>选择图标</Button>
                </Popover>
            )}
        </div>
    );
});

IconSelector.propTypes = {
    // 图标源配置
    iconfontClassName: PropTypes.string.isRequired,
    // 颜色列表
    colorList: PropTypes.array.isRequired,
    // 图标列表
    iconList: PropTypes.array.isRequired,
    // 是否默认选中第一个值
    defaultSelectFirstOption: PropTypes.bool,
    // 是否禁用
    disabled: PropTypes.bool,
    // 禁用的选项值
    disabledOptions: PropTypes.array
};

IconSelector.defaultProps = {
    defaultSelectFirstOption: false,
    disabled: false,
    disabledOptions: null
};
IconSelector.displayName = 'IconSelector';

export default IconSelector;
